/**
 * APITable <https://github.com/apitable/apitable>
 * Copyright (C) 2022 APITable Ltd. <https://apitable.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import { SystemConfig } from '@apitable/core';
import { ShortcutKey } from '@apitable/core/src/config/system_config.interface';
import { ShortcutActionName } from 'modules/shared/shortcut_key/enum';
import { browser } from '../browser';

export interface IKeyBinding {
  /**
   * mac key
   * key Mapping of keyboard key strings
   * can be found at . /keybinding/key_codes@define
   * You can also refer directly to vscode keyboard mapping
   */
  key: string;

  /**
   * windows key，If you don't have one, use the key
   */
  winKey?: string;

  /**
   * command name
   */
  command?: string;

  /**
   * Simple expressions can be written to support ! && == () ||
   * The variables supported in the expression can be found in . /shortcut_key/@ContextName
   */
  when?: string;

  /**
   * command function，Subsequent parsing converts the command key string to this function
   */
  commandFunc?: ShortcutActionName;

  /**
   * Categories, for interface display demarcation
   *
   * @type {string}
   * @memberof IKeyBinding
   */
  type?: string[];

  /**
   * The ID generated by the configuration table, usually equal to the key
   *
   * @type {string}
   * @memberof IKeyBinding
   */
  id?: string;

  /**
   * Shortcut names, Multilingual translation
   *
   * @type {string[]}
   * @memberof IKeyBinding
   */
  name?: string[];
}

export function getKeyForOS(keyBinding: IKeyBinding) {
  const { key, winKey } = keyBinding;
  return browser?.is('Windows') ? winKey || key : key;
}

// Macifying the display of shortcut keys
export function formatMacShortcutKey(shortcutKey: string): string {
  return shortcutKey
    .replace(/\+/g, ' ')
    .replace(/cmd/gi, '⌘')
    .replace(/option/gi, '⌥')
    .replace(/ctrl/gi, '⌃')
    .replace(/shift/gi, '⇧')
    .replace(/( up|^up)/gi, ' ↑')
    .replace(/( down|^down)/gi, ' ↓')
    .replace(/left/gi, '←')
    .replace(/right/gi, '→')
    .replace(/delete/gi, '⌫')
    .split(' ')
    .map((word) => word.slice(0, 1).toUpperCase() + word.slice(1))
    .join(' ')
    .trim();
}

// Winify the display of shortcut keys
export function formatWinShortcutKey(shortcutKey: string): string {
  return shortcutKey
    .replace(/(up$|^up)/gi, '↑')
    .replace(/(down$|^down)/gi, '↓')
    .replace(/left/gi, '←')
    .replace(/right/gi, '→')
    .split('+')
    .map((word) => word.slice(0, 1).toUpperCase() + word.slice(1))
    .join(' + ');
}

export function getShortcutKeyString(actionName: ShortcutActionName | ShortcutKey): string {
  let shortcutKey;
  if (typeof actionName === 'string') {
    shortcutKey = SystemConfig.shortcut_keys.find((item) => item.command === actionName);
  } else {
    shortcutKey = actionName;
  }
  if (!shortcutKey) {
    return '';
  }
  const { winKey, key } = shortcutKey;
  if (browser?.is('Windows')) {
    const keyVal = winKey || key;
    return formatWinShortcutKey(keyVal);
  }
  return formatMacShortcutKey(key);
}

// Converting arrays
export const keybindings = SystemConfig.shortcut_keys;
